	//---------------------------------------------------------------------
	// Includes
	//---------------------------------------------------------------------		
	#include <Geometry/Object.hpp>
	#include <Rendering/Shader.hpp>
	#include <Rendering/Renderer.hpp>
	
namespace Geometry {
	
	//---------------------------------------------------------------------			
	// Scene methods
	//---------------------------------------------------------------------				
	Scene::Scene() {
	}
	//---------------------------------------------------------------------		
	Scene::~Scene() {
	}
	//---------------------------------------------------------------------			
	void Scene::AddObject(const TObjectPointer& object) {
		objects.push_back(object);
	}
	//---------------------------------------------------------------------	
	void Scene::Render(Rendering::RenderingPass pass, Rendering::RenderingQueue& queue) {
		int nObjects = objects.size();
		for(int i=0;i<nObjects;++i) {
			objects[i]->Render(pass, queue);
		}		
	}
	
	
	
	//---------------------------------------------------------------------			
	// Object methods
	//---------------------------------------------------------------------				
	Object::Object(const Matrix::Matrix4& l2w, const TMeshPointer& m):
	mesh(m)	{
		Matrix::Copy4(localToWorldMatrix, l2w);
	}
	//---------------------------------------------------------------------				
	Object::~Object(){
	}
	//---------------------------------------------------------------------				
	//const TAABBPointer& GetWorldBound() const;
	//---------------------------------------------------------------------				
	const Matrix::Matrix4& Object::GetLocalToWorldTransformation() const{
		return localToWorldMatrix;
	}
	//---------------------------------------------------------------------				
	void Object::AddPass( Rendering::RenderingPass pass, 
						  const Rendering::TShaderProgramPointer& shader, 
						  const Rendering::TIShaderContextPointer& publicContext, 
						  const Rendering::TIShaderContextPointer& privateContext ) {
		// Create geometric context
		Rendering::TIShaderContextPointer geometricContext;
		geometricContext = Rendering::TIShaderContextPointer(new Rendering::GeometryContext(mesh, localToWorldMatrix));
		
		// Create environnement
		Rendering::TShaderEnvironnementPointer envPointer = Rendering::ShaderEnvironnement::CreateEnvironnement(shader);
		envPointer->Add(Rendering::PUBLIC_CONTEXT, publicContext);
		envPointer->Add(Rendering::PRIVATE_CONTEXT, privateContext);
		envPointer->Add(Rendering::GEOMETRIC_CONTEXT, geometricContext);
		
		// Compile & add environnement
		Rendering::ShaderCompilationReport report;
		envPointer->Compile(report);
		//if(!report.IsCompile())
			report.Print();
		assert(report.IsCompile());
		environnements[pass] = envPointer;
	}
	//---------------------------------------------------------------------
	void Object::Render(Rendering::RenderingPass pass, Rendering::RenderingQueue& queue  ) {
		// Search pass environnemment
		TEnvironnementPointerMap::iterator it;
		it = environnements.find(pass);
		
		// Add envirtonnement to queue
		//assert(it != environnements.end());
		if(it != environnements.end())
			queue.Add(it->second);			
	}
	//---------------------------------------------------------------------
	TObjectPointer Object::CreateObject(const Matrix::Matrix4& localToWorld, const TMeshPointer& mesh) {
		return TObjectPointer(new Object(localToWorld, mesh));
	}
	
}
